<!--
 * @description: 
 * @Author: Peng_Yong
 * @Date: 2023-08-22 09:13:50
 * @LastEditors: James324
 * @LastEditTime: 2024-03-25 09:35:50
-->
<script setup lang="ts">
import description from '@/views/Login/components/description.vue';
import qs from 'qs';
import { GlobalStore } from '@/store';
import { LocalStorage, validateEmoji, password } from '@/utils';
import { encryptRSA } from '@/utils/encipher'; // TODO: 删除
import { LOGIN_LOGIN_FORM } from '@/config';
import type { FormInstance, FormRules } from 'element-plus';

defineOptions({
    name: 'Login'
});

const globalStore = GlobalStore();
const route = useRoute();
const router = useRouter();
const rememberPassword = ref(false); // 记住密码
const showRef = ref(false); // 是否展示密码
const loading = ref(false);
const formRef = ref<FormInstance>();
const loginFormRef = ref({
    username: '',
    password: ''
});

onBeforeMount(() => {
    handleInitForm();
});

// 初始化表单数据
const handleInitForm = () => {
    const formObj = LocalStorage.get(LOGIN_LOGIN_FORM);
    if (formObj?.username) {
        rememberPassword.value = true;
        loginFormRef.value = {
            username: formObj.username,
            password: formObj.password
        };
    } else {
        loginFormRef.value = {
            username: import.meta.env.VITE_APP_PHONE || '',
            password: import.meta.env.VITE_APP_PASSWORD || ''
        };
    }
};

let passwordRight = true;
let errMsg = '';

// 校验密码错误
const validatePassword = (_: any, __: string, callback: (option?: any) => void) => {
    if (passwordRight) {
        callback();
    } else {
        callback(new Error(errMsg));
        passwordRight = true;
    }
};

// 校验规则
const rules: FormRules = {
    username: [
        { required: true, message: '用户名为必填项', trigger: 'blur' },
        { min: 1, max: 11, message: '最大仅支持11个字符', trigger: 'blur' },
        {
            pattern: password,
            message: '字母开头，允许字母、数字、下划线',
            trigger: 'blur'
        }
    ],
    password: [
        { required: true, message: '密码为必填项', trigger: 'blur' },
        { min: 1, max: 11, message: '密码需要在6-11位之间', trigger: 'blur' },
        {
            pattern: password,
            message: '字母开头，允许字母、数字、下划线',
            trigger: 'blur'
        },
        { validator: validateEmoji, trigger: 'blur' },
        { validator: validatePassword, trigger: 'blur' }
    ]
};

const setLoading = (val: boolean) => (loading.value = val);

/**
 * @: 点击登录
 * @param {*} useThrottleFn
 * @return {*}
 */
const usernameRef = ref();
const handleLogin = async () => {
    formRef.value?.clearValidate();
    if (loading.value) return;
    setLoading(true);
    try {
        usernameRef.value.blur(); // 兼容回车事件避免重新调用接口
        await formRef.value?.validate();
        const password = encryptRSA(loginFormRef.value.password);
        const username = loginFormRef.value.username;
        const form = { username, password };
        await globalStore.login(form);
        const redirect = route.query.redirect as string;
        const queryString = redirect.split('?')[1] || {}; // 获取 query 参数
        const queryParams = qs.parse(queryString);

        if (rememberPassword.value) {
            LocalStorage.set(LOGIN_LOGIN_FORM, loginFormRef.value);
        } else {
            LocalStorage.remove(LOGIN_LOGIN_FORM);
        }

        setLoading(false);
        router.replace({
            path: redirect || '/home',
            query: queryParams as any
        });
    } catch (error: any) {
        errMsg = error.data?.msg || '系统错误';
        if (error.data?.code === 9) {
            errMsg = '密码错误';
            passwordRight = false;
            formRef.value?.validateField('password');
        }
    }
    setLoading(false);
};
</script>

<template>
    <div class="main">
        <description />
        <div class="login">
            <div class="login__title">
                灯塔APS高级计划排程系统
                <div class="login__title--line"></div>
            </div>
            <el-form
                ref="formRef"
                class="form"
                :model="loginFormRef"
                :rules="rules"
                @keyup.enter="handleLogin"
            >
                <!-- 账号 -->
                <el-form-item class="form-item" prop="username">
                    <el-input
                        ref="usernameRef"
                        v-model.trim="loginFormRef.username"
                        placeholder="请输入登录账号"
                    >
                        <template #prefix>
                            <div class="login__prefix">
                                <q-icon icon-class="denglu" color="#272636" />
                            </div>
                        </template>
                    </el-input>
                </el-form-item>

                <!-- 密码 -->
                <el-form-item prop="password">
                    <el-input
                        v-model.trim="loginFormRef.password"
                        placeholder="请输入登密码"
                        :type="showRef ? 'text' : 'password'"
                    >
                        <template #prefix>
                            <div class="login__prefix">
                                <q-icon icon-class="a-mima1" color="#272636" size="24px" />
                            </div>
                        </template>
                    </el-input>
                    <div class="login__password-show" @click.stop="showRef = !showRef">
                        <el-icon class="u-password__icon">
                            <i-ep-view v-show="showRef" />
                            <i-ep-hide v-show="!showRef" />
                        </el-icon>
                    </div>
                </el-form-item>

                <!-- 记住密码 -->
                <div class="login__operate">
                    <el-checkbox v-model="rememberPassword">
                        <div>记住密码</div>
                    </el-checkbox>

                    <el-link v-show="false" type="primary" :underline="false">忘记密码?</el-link>
                </div>

                <!-- 登录 -->
                <el-form-item prop="login">
                    <el-button
                        :class="['login__btn', { 'is-pending': loading }]"
                        type="primary"
                        auto-insert-space
                        @click="handleLogin"
                    >
                        <q-loading v-if="loading" class="u-login__icon" />
                        <span>登录</span>
                    </el-button>
                </el-form-item>
            </el-form>
        </div>
        <p class="copyright">
            Copyright © 2016-2024 灯塔APS. All Rights Reserved 宁波启山科技有限公司版权所有
        </p>
    </div>
</template>

<style lang="scss" scoped>
@include b(main) {
    position: relative;
    display: flex;
    align-items: center;
    min-width: 1270px;
    height: 100%;
    background: url('@/assets/img/login.jpg') no-repeat top center;
    background-size: 100% 100%;

    .copyright {
        bottom: 20px;
    }
}

// login弹框
@include b(login) {
    position: absolute;
    right: 11vw;
    z-index: 6;
    box-sizing: border-box;
    width: 25vw;
    height: 30vw;
    padding: 3.8021vw 3.2813vw 5.3646vw;
    overflow: hidden;
    font-size: 0.9vw;
    background-color: #fff;
    border-radius: 20px;

    // 标题
    @include e(title) {
        font-size: 1.4vw;
        color: #000;
        text-align: center;

        @include m(line) {
            position: relative;
            width: 2.5vw;
            height: 0.25vw;
            margin: 0.9vw auto 0;
            background: #409eff;
        }
    }

    @include e(operate) {
        display: flex;
        align-items: center;
        justify-content: space-between;
        color: var(--q-text-color-secondary);
    }

    @include e(prefix) {
        position: relative;
        display: flex;
        align-items: center;
        padding-right: 10px;

        &::after {
            position: absolute;
            top: 2px;
            right: 0;
            bottom: 2px;
            content: '';
            border-right: 1px solid var(--q-color-info-light-8);
        }
    }

    @include e(password-show) {
        position: absolute;
        right: 10px;
        z-index: 6;
        display: flex;
        align-items: center;
        height: 100%;
        color: var(--q-text-color-secondary);
        cursor: pointer;
    }

    @include e(btn) {
        width: 100%;
        height: 3.15vw;
        margin-top: 2vw;
        font-size: 1.25vw;

        @include when(pending) {
            opacity: 0.6;
        }

        :deep(.el-button__text--expand) {
            letter-spacing: 0.6vw;
        }
    }
}

@include b(suffix) {
    width: 1vw;
}

@include b(form) {
    margin-top: 3vw;
}

@include b(el-form-item) {
    margin-bottom: 2vw;

    @include when(error) {
        :deep(.el-input__wrapper) {
            box-shadow: 0 0 0 2px var(--el-color-danger) inset !important;
            animation-name: error-animation;
            animation-duration: 0.2s;
            animation-timing-function: ease-in-out;
            animation-iteration-count: 5;

            &::before,
            &::after {
                width: 0 !important;
                height: 0 !important;
            }
        }
    }
}

// input动画
@include b(el-input) {
    height: 3vw;
    font-size: 0.88vw;

    :deep(.el-input__wrapper) {
        overflow: hidden;
        background: #f2f4f9;

        --el-input-border-color: #fff;
        --el-input-focus-border-color: #fff;
        --el-input-hover-border-color: #fff;

        @include e(inner) {
            caret-color: #409eff;

            &::placeholder {
                color: var(--q-color-info-light-8);
            }
        }

        &::before,
        &::after {
            position: absolute;
            box-sizing: border-box;
            width: 0;
            height: 0;
            content: ' ';
            border: 1px solid transparent;
        }

        &::before {
            top: 0;
            left: 0; /* 鼠标离开后的回退效果，如果不设置回退效果，则鼠标离开后就直接很生硬的隐藏了 */
            transition:
                border-color 1s ease-in,
                width 0.3s ease-in 0.2s,
                height 0.1s ease-in;
        }

        &::after {
            right: 0;
            bottom: 0;
            transition:
                width 0.3s ease-in 0.2s,
                height 0.1s ease-in;
        }

        &.is-focus::before,
        &.is-focus::after {
            width: 100%;
            height: 100%;
            border-width: 2px;
        }

        &.is-focus::after {
            border-image: linear-gradient(270deg, #5581f1 0%, #1153fc 100%) 1;
            border-image-width: 0 0 2px 2px;
            transition:
                border-image 1s,
                width 0.4s ease-out,
                height 0.3s ease-in-out 0.3s,
                border-width 0.2s ease-out;
        }

        &.is-focus::before {
            border-image: linear-gradient(270deg, #5581f1 0%, #1153fc 100%) 1;
            border-image-width: 2px 2px 0 0;
            transition:
                border-image 1s,
                width 0.4s ease-out,
                border-width 0.2s ease-out,
                height 0.3s ease-in-out 0.3s;
        }
    }
}

@include b(u-login) {
    @include e(icon) {
        font-size: 24px !important;
    }
}

@include b(u-password) {
    @include e(icon) {
        font-size: 18px;
    }
}

// 错误动画
@keyframes error-animation {
    0% {
        transform: translateY(-2px);
    }

    25% {
        transform: translateY(-1px);
    }

    50% {
        transform: translateY(0);
    }

    75% {
        transform: translateY(1px);
    }

    100% {
        transform: translateY(2px);
    }
}

@media (width < 1270px) {
    @include b(login) {
        right: 158.75px;
        width: 317.5px;
        height: 381px;
        padding: 48px 41px 68px;
        font-size: 11.43px;

        // 标题
        @include e(title) {
            font-size: 17.78px;

            @include m(line) {
                width: 31.75px;
                height: 3.175px;
                margin: 11.43px auto 0;
            }
        }

        @include e(btn) {
            height: 40px;
            margin-top: 25.4px;
            font-size: 15px;
        }
    }

    @include b(suffix) {
        width: 12.7px;
    }

    @include b(el-form-item) {
        margin-bottom: 25.4px;
    }

    @include b(form) {
        margin-top: 38px;
    }

    @include b(el-input) {
        height: 38px;
        font-size: 11px;
    }

    @include b(u-password) {
        @include e(icon) {
            font-size: 14px;
        }
    }

    @include b(u-login) {
        @include e(icon) {
            font-size: 18px !important;
        }
    }
}
</style>
